package com.invient.math.test;

import junit.framework.TestCase;
import static org.junit.Assert.*;

import com.invient.math.Vector2f;

public class Vector2fTest extends TestCase
{
    private static final float DELTA = 0.001f;
    
    public void testDefaultConstructor() {
        Vector2f vector = new Vector2f();
        assertEquals(0.0f, vector.getX());
        assertEquals(0.0f, vector.getY());
    }
    
    public void testParameterConstructor() {
        final float x = 3.42f;
        final float y = 6.34f;
        Vector2f vector = new Vector2f(x, y);
        assertEquals(x, vector.getX());
        assertEquals(y, vector.getY());
    }
    
    public void testArrayConstructor() {
        final float x = 3.54f;
        final float y = 6.35f;
        final float[] array = {x, y};
        Vector2f vector = new Vector2f(array);
        assertEquals(x, vector.getX());
        assertEquals(y, vector.getY());
    }
    
    public void testSet() 
        throws ArrayIndexOutOfBoundsException {
        final float value = 4.324f;
        
        Vector2f vector = new Vector2f();
        vector.set(0, value);
        assertEquals(value, vector.getX());
        
        try {
            vector.set(3, value);
        }
        catch(ArrayIndexOutOfBoundsException e){}
        
        try {
            vector.set(-1, value);
        }
        catch(ArrayIndexOutOfBoundsException e){}
        
        vector.set(1, value);
        assertEquals(value, vector.getY());
    }
    
    public void testGet() 
        throws ArrayIndexOutOfBoundsException {
        final float x = 4.346f;
        final float y = 6.349f;
        
        Vector2f vector = new Vector2f(x, y);
        assertEquals(x, vector.get(0));
        assertEquals(y, vector.get(1));
        
        try {
            float error = vector.get(3);
        }
        catch(ArrayIndexOutOfBoundsException e){}
        
        try {
            float error = vector.get(-1);
        }
        catch(ArrayIndexOutOfBoundsException e){}
    }
    
    public void testDot()
        throws IllegalArgumentException {
        final float x1 = 4.0f;
        final float y1 = 6.0f;
        final float x2 = 3.0f;
        final float y2 = 7.0f;
        final float actualDot = 54.0f;
        
        Vector2f vector1 = new Vector2f(x1, y1);
        Vector2f vector2 = new Vector2f(x2, y2);
        
        float dot = vector1.dot(vector2);
        assertEquals(actualDot, dot, DELTA);
        
        try {
            vector1.dot(null);
        }
        catch(IllegalArgumentException e){}
    }
    
    public void testLength() {
        final float x = 4.34f;
        final float y = 6.43f;
        final float actualLength = 7.75761f;
        
        Vector2f vector = new Vector2f(x, y);
        float length = vector.length();
        assertEquals(actualLength, length, DELTA);
    }
    
    public void testAdd()
        throws IllegalArgumentException {
        final float x1 = 4.43f;
        final float y1 = 6.63f;
        final float x2 = 2.25f;
        final float y2 = 8.36f;
        final float resultX = 6.68f;
        final float resultY = 14.99f;
        
        Vector2f vector1 = new Vector2f(x1, y1);
        Vector2f vector2 = new Vector2f(x2, y2);
        
        vector1.add(vector2);
        assertEquals(resultX, vector1.getX(), DELTA);
        assertEquals(resultY, vector1.getY(), DELTA);
        
        try {
            vector1.add(null);
        }
        catch(IllegalArgumentException e){}
    }
    
    public void testSubtract()
        throws IllegalArgumentException {
        final float x1 = 4.43f;
        final float y1 = 6.63f;
        final float x2 = 2.25f;
        final float y2 = 8.36f;
        final float resultX = 2.18f;
        final float resultY = -1.73f;
        
        Vector2f vector1 = new Vector2f(x1, y1);
        Vector2f vector2 = new Vector2f(x2, y2);
        
        vector1.subtract(vector2);
        assertEquals(resultX, vector1.getX(), DELTA);
        assertEquals(resultY, vector1.getY(), DELTA);
        
        try {
            vector1.add(null);
        }
        catch(IllegalArgumentException e){}
    }
    
    public void testSetVector()
        throws IllegalArgumentException {
        final float x = 4.43f;
        final float y = 6.47f;
        
        Vector2f vector1 = new Vector2f(x, y);
        Vector2f vector2 = new Vector2f();
        
        vector2.set(vector1);
        assertEquals(x, vector2.getX());
        assertEquals(y, vector2.getY());
        
        try {
            vector1.set(null);
        }
        catch(IllegalArgumentException e){}
    }
    
    public void testDistance()
        throws IllegalArgumentException {
        final float x = 4.2f;
        final float y = 3.5f;
        final float actualDistance = 5.46717f;
        
        Vector2f vector1 = new Vector2f(x, y);
        Vector2f vector2 = new Vector2f();
        
        float distance = vector1.distance(vector2);
        assertEquals(actualDistance, distance, DELTA);
        
        try {
            vector1.distance(null);
        }
        catch(IllegalArgumentException e){}
    }
    
    public void testNormalize() {
        final float x = 4.0f;
        final float y = 5.0f;
        final float actualNormalizedX = 0.624695f;
        final float actualNormalizedY = 0.780869f;
        
        Vector2f vector = new Vector2f(x, y);
        vector.normalize();
        float normalizedX = vector.getX();
        float normalizedY = vector.getY();
        assertEquals(actualNormalizedX, normalizedX, DELTA);
        assertEquals(actualNormalizedY, normalizedY, DELTA);
    }
    
    public void testInverse() {
        final float x = 5.34f;
        final float y = 8.54f;
        
        Vector2f vector = new Vector2f(x, y);
        vector.inverse();
        assertEquals(-x, vector.getX());
        assertEquals(-y, vector.getY());
    }
    
    public void testMultiplyByScalar() {
        final float x = 5.34f;
        final float y = 3.53f;
        final float scalar = 2.52f;
        final float resultX = 13.4568f;
        final float resultY = 8.8956f;
        
        Vector2f vector = new Vector2f(x, y);
        vector.multiplyByScalar(scalar);
        assertEquals(resultX, vector.getX(), DELTA);
        assertEquals(resultY, vector.getY(), DELTA);
    }
    
    public void testGetSet() {
        final float x = 4.63f;
        final float y = 6.23f;
        
        Vector2f vector = new Vector2f();
        vector.setX(x);
        vector.setY(y);
        assertEquals(x, vector.getX());
        assertEquals(y, vector.getY());
    }
    
    public void testStaticDot() {
        final float x1 = 3.45f;
        final float y1 = 2.64f;
        final float x2 = 7.43f;
        final float y2 = 5.45f;
        final float actualDot = 40.0215f;
        
        Vector2f vector1 = new Vector2f(x1, y1);
        Vector2f vector2 = new Vector2f(x2, y2);
        
        float dot = Vector2f.dot(vector1, vector2);
        assertEquals(actualDot, dot, DELTA);
    }
    
    public void testStaticAdd()
        throws IllegalArgumentException {
        
        final float x1 = 4.34f;
        final float y1 = 2.52f;
        final float x2 = 7.35f;
        final float y2 = 5.43f;
        final float resultX = 11.69f;
        final float resultY = 7.95f;
        
        Vector2f vector1 = new Vector2f(x1, y1);
        Vector2f vector2 = new Vector2f(x2, y2);
        Vector2f result = Vector2f.add(vector1, vector2);
        assertEquals(resultX, result.getX(), DELTA);
        assertEquals(resultY, result.getY(), DELTA);
        
        try {
            Vector2f.add(null, vector1);
        }
        catch(IllegalArgumentException e){}
        
        try {
            Vector2f.add(vector1, null);
        }
        catch(IllegalArgumentException e){}
        
        try {
            Vector2f.add(null, null);
        }
        catch(IllegalArgumentException e){}
    }
    
    public void testStaticSubtract()
        throws IllegalArgumentException {
        
        final float x1 = 4.34f;
        final float y1 = 2.52f;
        final float x2 = 7.35f;
        final float y2 = 5.43f;
        final float resultX = -3.01f;
        final float resultY = -2.91f;
        
        Vector2f vector1 = new Vector2f(x1, y1);
        Vector2f vector2 = new Vector2f(x2, y2);
        Vector2f result = Vector2f.subtract(vector1, vector2);
        assertEquals(resultX, result.getX(), DELTA);
        assertEquals(resultY, result.getY(), DELTA);
        
        try {
            Vector2f.subtract(null, vector1);
        }
        catch(IllegalArgumentException e){}
        
        try {
            Vector2f.subtract(vector1, null);
        }
        catch(IllegalArgumentException e){}
        
        try {
            Vector2f.subtract(null, null);
        }
        catch(IllegalArgumentException e){}
    }
    
    public void testStaticNormalize()
        throws IllegalArgumentException {
        
        final float x = 3.43f;
        final float y = 5.34f;
        final float normalizedX = 0.5404f;
        final float normalizedY = 0.8414f;
        
        Vector2f vector = new Vector2f(x, y);
        Vector2f result = Vector2f.normalize(vector);
        assertEquals(normalizedX, result.getX(), DELTA);
        assertEquals(normalizedY, result.getY(), DELTA);
        
        try {
            Vector2f.normalize(null);
        }
        catch(IllegalArgumentException e){}
    }
    
    public void testStaticInverse()
        throws IllegalArgumentException {
        
        final float x = 4.32f;
        final float y = 6.35f;
        
        Vector2f vector = new Vector2f(x, y);
        Vector2f result = Vector2f.inverse(vector);
        
        assertEquals(-x, result.getX());
        assertEquals(-y, result.getY());
        
        try {
            Vector2f.inverse(null);
        }
        catch(IllegalArgumentException e){}
    }
    
    public void testStaticConvertToVector()
        throws IllegalArgumentException {
        
        final float x1 = 4.0f;
        final float y1 = 5.0f;
        final float x2 = 8.0f;
        final float y2 = 9.0f;
        final float resultX = 4.0f;
        final float resultY = 4.0f;
        
        Vector2f vector1 = new Vector2f(x1, y1);
        Vector2f vector2 = new Vector2f(x2, y2);
        Vector2f result = Vector2f.convertToVector(vector1, vector2);
        
        assertEquals(resultX, result.getX());
        assertEquals(resultY, result.getY());
        
        try {
            Vector2f.convertToVector(null, vector1);
        }
        catch(IllegalArgumentException e){}
        
        try {
            Vector2f.convertToVector(vector1, null);
        }
        catch(IllegalArgumentException e){}
        
        try {
            Vector2f.convertToVector(null, null);
        }
        catch(IllegalArgumentException e){}
    }
    
    public void testStaticDistance()
        throws IllegalArgumentException {
        
        final float x1 = 4.3f;
        final float y1 = 5.3f;
        final float x2 = 2.9f;
        final float y2 = 8.4f;
        final float actualDistance = 3.4015f;
        
        Vector2f vector1 = new Vector2f(x1, y1);
        Vector2f vector2 = new Vector2f(x2, y2);
        float distance = Vector2f.distance(vector1, vector2);
        assertEquals(actualDistance, distance, DELTA);
    }
}